/*
	klib_message_passing.h

	contains headers for IPC message passing functions

	Author: Aidan Goddard 21/8/13
*/

#ifndef MESSAGE_PASSING_H_INCLUDED
#define MESSAGE_PASSING_H_INCLUDED

///////////////////////////////////////////////////////////////////////
//// error codes

#define MSG_SUCCESS 		0
#define MSG_MSG_EXIST		0
#define MSG_NO_MSG_EXIST	0xfffffff7
#define MSG_NO_CHANNEL		0xffffffff // channel does not exist
#define MSG_NOT_SERVER		0xfffffffe // caller is not the server process
#define MSG_NOT_CLIENT		0xfffffffd // caller is not the client process/module
#define MSG_INVALID_CHANNEL	0xfffffffc // the given channel ID is not valid
#define MSG_CHANNEL_BOUND	0xfffffffb // the given channel is already bound to a client
#define MSG_READ_CONT		0xfffffffa // there is read contention on the given channel
#define MSG_WRITE_CONT		0xfffffff9 // there is write contention on the given channel
#define MSG_PREMATURE_WAKE	0xfffffff8 // the thread was woken prematurely, probably by something else
#define MSG_BUFFER_FULL		0xfffffff6 // the buffer is full

typedef uint64_t MSG_CHANNEL;

///////////////////////////////////////////////////////////////////////
//// functions

MSG_CHANNEL	__KLIB__MSGAllocateChannel(char *magic_string, uint32_t magic_int);
uint32_t	__KLIB__MSGDeallocateChannel(MSG_CHANNEL channel);
MSG_CHANNEL __KLIB__MSGFindChannel(char *magic_string, uint32_t magic_int);
uint32_t	__KLIB__MSGClientBindChannel(MSG_CHANNEL channel, uint64_t PID);

// message read functions
uint32_t	__KLIB__MSGServerRead(MSG_CHANNEL channel, uint8_t *buffer);
uint32_t	__KLIB__MSGServerPeek(MSG_CHANNEL channel);
uint32_t	__KLIB__MSGClientRead(MSG_CHANNEL channel, uint8_t *buffer, uint64_t PID);
uint32_t	__KLIB__MSGClientPeek(MSG_CHANNEL channel, uint64_t PID);

// message send functions
uint32_t	__KLIB__MSGServerSendSync(MSG_CHANNEL channel, uint8_t *buffer);
uint32_t 	__KLIB__MSGServerSendAsync(MSG_CHANNEL channel, uint8_t *buffer);
uint32_t 	__KLIB__MSGClientSendSync(MSG_CHANNEL channel, uint8_t *buffer, uint64_t PID);
uint32_t 	__KLIB__MSGClientSendAsync(MSG_CHANNEL channel, uint8_t *buffer, uint64_t PID);

// functions for querying the number of pending messages in a buffer (can be called by anyone as long as the channel is correct)
uint32_t	__KLIB__MSGGetClientPendingMessages(MSG_CHANNEL channel);
uint32_t	__KLIB__MSGGetServerPendingMessages(MSG_CHANNEL channel);


#endif
